using System;
using System.Collections.Generic;
using System.Text;
using SpriteCraft;
using System.Drawing;

namespace SpaceGame
{
  public abstract class Ship
  {
    protected EngineClass m_Engine;
    protected Player m_Player;

    protected const int WARBOT_SPEED = 200;

    public virtual float X
    {
      get
      {
        return 0f;
      }
      protected set
      {
      }
    }

    public virtual float Y
    {
      get
      {
        return 0f;
      }
      protected set
      {
      }
    }

    public Ship(EngineClass engine, Player player, int collideGroup)
    {
      m_Engine = engine;
      m_Player = player;
    }

    public virtual void DoStuff(Stage stage, int tickdelta, Point targetpos)
    {
      int leftright = 0, updown = 0;

      if (targetpos.X > this.X) { leftright = +1; }
      else if (targetpos.X < this.X) { leftright = -1; }

      if (targetpos.Y > this.Y) { updown = +1; }
      else if (targetpos.Y < this.Y) { updown = -1; }

      //Defining new space ship coordinates.
      float dx = (WARBOT_SPEED * leftright * tickdelta) / 1000;
      if (Math.Abs(dx) > Math.Abs(this.X - targetpos.X))
      { dx = 0; }
      this.X += dx;

      if (updown > 0)
      {
        float dy = (WARBOT_SPEED * updown * tickdelta) / 1000;
        if (Math.Abs(dy) > Math.Abs(this.Y - targetpos.Y))
        { dy = 0; }

        this.Y += dy;
      }
      else
      {
        this.Y = this.Y + (WARBOT_SPEED * updown * tickdelta) / 1000;
      }

      //Check that the ship doesn't leave the "safe" screen area:  
      if (this.X < stage.Min_x)
      {
        this.X = stage.Min_x;
      }
      else if (this.X > stage.Max_x)
      {
        this.X = stage.Max_x;
      }

      if (this.Y < stage.Min_y)
      {
        this.Y = stage.Min_y;
      }
      else if (this.Y > stage.Max_y)
      {
        this.Y = stage.Max_y;
      }
    }

    public virtual void DoStuff(Stage stage, int tickdelta, long leftright, long updown)
    {
      //Defining new space ship coordinates.
      this.X = this.X + (WARBOT_SPEED * leftright * tickdelta) / 1000;
      if (updown > 0)
      {
        this.Y = this.Y + (WARBOT_SPEED * updown * tickdelta) / 1000;
      }
      else
      {
        this.Y = this.Y + (WARBOT_SPEED * updown * tickdelta) / 1000;
      }

      //Check that the ship doesn't leave the "safe" screen area:  
      if (this.X < stage.Min_x)
      {
        this.X = stage.Min_x;
      }
      else if (this.X > stage.Max_x)
      {
        this.X = stage.Max_x;
      }

      if (this.Y < stage.Min_y)
      {
        this.Y = stage.Min_y;
      }
      else if (this.Y > stage.Max_y)
      {
        this.Y = stage.Max_y;
      }
    }

    public abstract void Hit();
  }

  public class SmallFighterShip : Ship
  {
    //sprites for the ship frame and its trails.
    private ISprite warbot;
    private ISprite leftTrak;
    private ISprite rightTrak;


    public override float X
    {
      get
      {
        return warbot.x;
      }
      protected set
      {
        warbot.x = value;
      }
    }

    public override float Y
    {
      get
      {
        return warbot.y;
      }
      protected set
      {
        warbot.y = value;
      }
    }

    public SmallFighterShip(EngineClass engine, Player player, int collideGroup, Point startpoint)
      : base(engine, player, collideGroup)
    {
      //A sprite for the ship frame is initially located 
      //at the center-bottom area of the screen.
      warbot = engine.NewSprite_("player_circle", 0);
      warbot.frno = 1;
      warbot.hotspot = tagHotspot.HotspotCenter;
      warbot.subimpl = player;
      warbot.collide = collideGroup;
      warbot.x = startpoint.X;
      warbot.y = startpoint.Y;

      //These trail sprites are signed as child sprites of the ship sprite. 
      //Their coordinates are relative to the ship sprite.
      leftTrak = engine.NewSprite_("player_trak", 0);
      leftTrak.parent = warbot;
      leftTrak.x = -14;
      leftTrak.y = -5;

      rightTrak = engine.NewSprite_("player_trak", 0);
      rightTrak.parent = warbot;
      rightTrak.x = -14;
      rightTrak.y = 5;
    }

    public override void DoStuff(Stage stage, int tickdelta, long leftright, long updown)
    {
      base.DoStuff(stage, tickdelta, leftright, updown);

      //Depending of the ship's horizontal direction, we can change 
      //its appearance, by changing sprite's frame number.
      if (updown < 0)
      {
        warbot.frno = 0;
      }
      else if (updown > 0)
      {
        warbot.frno = 2;
      }
      else
      {
        warbot.frno = 1;
      }

      //Depending of the ship's vertical direction, we can show acceleration 
      //or deceleration, by scaling its trails vertically.
      if (leftright > 0)
      {
        leftTrak.xScale = 150;
        rightTrak.xScale = 150;
      }
      else if (leftright < 0)
      {
        leftTrak.xScale = 50;
        rightTrak.xScale = 50;
      }
      else
      {
        leftTrak.xScale = 100;
        rightTrak.xScale = 100;
      }
    }

    public override void Hit()
    {
      warbot.Hit(warbot);
    }
  }
}
